package owl;

import java.util.Map;
import java.util.Set;

import org.semanticweb.owlapi.expression.ParserException;
import org.semanticweb.owlapi.model.OWLClass;
import org.semanticweb.owlapi.model.OWLDataPropertyExpression;
import org.semanticweb.owlapi.model.OWLEntity;
import org.semanticweb.owlapi.model.OWLLiteral;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.semanticweb.owlapi.util.ShortFormProvider;

public class DLQueryPrinter {
	private DLQueryEngine dlQueryEngine;
	private ShortFormProvider shortFormProvider;

	/**
	 * @param engine
	 *            the engine
	 * @param shortFormProvider
	 *            the short form provider
	 */
	public DLQueryPrinter(DLQueryEngine engine,
			ShortFormProvider shortFormProvider) {
		this.shortFormProvider = shortFormProvider;
		dlQueryEngine = engine;
	}

	/**
	 * @param classExpression
	 *            the class expression to use for interrogation
	 */
	public String askQuery(String classExpression) {
		String str;
		if (classExpression.length() == 0) {
			str = "No class expression specified";
		} else {
			try {
				StringBuilder sb = new StringBuilder();
				sb.append("\n--------------------------------------------------------------------------------\n");
				sb.append("QUERY:   ");
				sb.append(classExpression);
				sb.append("\n");
				sb.append("--------------------------------------------------------------------------------\n\n");
				// Ask for the subclasses, superclasses etc. of the specified
				// class expression. Print out the results.
				Set<OWLClass> superClasses = dlQueryEngine.getSuperClasses(
						classExpression, false);
				printEntities("SuperClasses", superClasses, sb);
				Set<OWLClass> equivalentClasses = dlQueryEngine
						.getEquivalentClasses(classExpression);
				printEntities("EquivalentClasses", equivalentClasses, sb);
				Set<OWLClass> subClasses = dlQueryEngine.getSubClasses(
						classExpression, false);
				printEntities("SubClasses", subClasses, sb);
				Set<OWLNamedIndividual> individuals = dlQueryEngine
						.getInstances(classExpression, false);
				printInstances("All Instances", individuals, sb);
				str = sb.toString();
			} catch (ParserException e) {
				str = e.getMessage();
			}
		}
		return str;
	}

	private void printEntities(String name, Set<? extends OWLEntity> entities,
			StringBuilder sb) {
		sb.append(name);
		int length = 50 - name.length();
		for (int i = 0; i < length; i++) {
			sb.append(".");
		}
		sb.append("\n\n");
		if (!entities.isEmpty()) {
			for (OWLEntity entity : entities) {
				sb.append("\t");
				sb.append(shortFormProvider.getShortForm(entity));
				sb.append("\n");
			}
		} else {
			sb.append("\t[NONE]\n");
		}
		sb.append("\n");
	}

	private void printInstances(String name, Set<OWLNamedIndividual> entities,
			StringBuilder sb) {
		sb.append(name);
		int length = 50 - name.length();
		for (int i = 0; i < length; i++) {
			sb.append(".");
		}
		sb.append("\n\n");
		if (!entities.isEmpty()) {
			for (OWLNamedIndividual entity : entities) {
				sb.append("\t");
				sb.append(shortFormProvider.getShortForm(entity));
				sb.append("   :");
				Map<OWLDataPropertyExpression, Set<OWLLiteral>> data = entity
						.getDataPropertyValues(dlQueryEngine.reasoner
								.getRootOntology());
				Set<OWLDataPropertyExpression> keys = data.keySet();
				for (OWLDataPropertyExpression key : keys) {
					sb.append("\n \t \t");
					String keyStr = key.toString();
					String shorkey = keyStr.substring(keyStr.indexOf('#') + 1,
							keyStr.length() - 1);
					sb.append(shorkey + " :");
					Set<OWLLiteral> vas = data.get(key);
					for (OWLLiteral v : vas) {
						String str = v.getLiteral();
						str = str.replaceAll("\n", "    ");
						sb.append(str);
					}
				}
				sb.append("\n");
			}
		} else {
			sb.append("\t[NONE]\n");
		}
		sb.append("\n");
	}
}
